/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ohosannotations.holder;

import static com.helger.jcodemodel.JExpr._super;

import java.util.HashMap;
import java.util.Map;

import com.helger.jcodemodel.JBlock;
import com.helger.jcodemodel.JCase;
import com.helger.jcodemodel.JExpr;
import com.helger.jcodemodel.JMethod;
import com.helger.jcodemodel.JMod;
import com.helger.jcodemodel.JSwitch;
import com.helger.jcodemodel.JVar;

/**
 * 在能力结果委托
 *
 * @author dev
 * @since 2021-07-22
 */
public class OnAbilityResultDelegate extends GeneratedClassHolderDelegate<EComponentHolder> {
    private JMethod method;
    private JBlock afterSuperBlock;
    private JSwitch zwitch;
    private JVar requestCodeParam;
    private JVar dataParam;
    private JVar resultCodeParam;
    private Map<Integer, JBlock> caseBlocks = new HashMap<>();

    /**
     * 在能力结果委托
     *
     * @param holder 持有人
     */
    public OnAbilityResultDelegate(EComponentHolder holder) {
        super(holder);
    }

    /**
     * get方法
     *
     * @return {@link JMethod}
     */
    public JMethod getMethod() {
        if (method == null) {
            setOnAbilityResult();
        }
        return method;
    }

    /**
     * get请求代码参数
     *
     * @return {@link JVar}
     */
    public JVar getRequestCodeParam() {
        if (requestCodeParam == null) {
            setOnAbilityResult();
        }
        return requestCodeParam;
    }


    /**
     * 获取数据参数
     *
     * @return {@link JVar}
     */
    public JVar getDataParam() {
        if (dataParam == null) {
            setOnAbilityResult();
        }
        return dataParam;
    }

    /**
     * 得到的结果代码参数
     *
     * @return {@link JVar}
     */
    public JVar getResultCodeParam() {
        if (dataParam == null) {
            setOnAbilityResult();
        }
        return resultCodeParam;
    }

    /**
     * 得到情况下块
     *
     * @param requestCode 请求的代码
     * @return {@link JBlock}
     */
    public JBlock getCaseBlock(int requestCode) {
        JBlock onAbilityResultCaseBlock = caseBlocks.get(requestCode);
        if (onAbilityResultCaseBlock == null) {
            onAbilityResultCaseBlock = createCaseBlock(requestCode);
            caseBlocks.put(requestCode, onAbilityResultCaseBlock);
        }
        return onAbilityResultCaseBlock;
    }


    private JBlock createCaseBlock(int requestCode) {
        JCase onAbilityResultCase = getSwitch()._case(JExpr.lit(requestCode));
        JBlock onAbilityResultCaseBlock = onAbilityResultCase.body().blockSimple();
        onAbilityResultCase.body()._break();
        return onAbilityResultCaseBlock;
    }


    /**
     * 把开关
     *
     * @return {@link JSwitch}
     */
    public JSwitch getSwitch() {
        if (zwitch == null) {
            setSwitch();
        }
        return zwitch;
    }


    private void setSwitch() {
        zwitch = getAfterSuperBlock()._switch(getRequestCodeParam());
    }


    /**
     * 后得到超级块
     *
     * @return {@link JBlock}
     */
    public JBlock getAfterSuperBlock() {
        if (afterSuperBlock == null) {
            setOnAbilityResult();
        }
        return afterSuperBlock;
    }

    private void setOnAbilityResult() {
        method = holder.getGeneratedClass().method(JMod.PUBLIC, codeModel().VOID, "onAbilityResult");
        method.annotate(Override.class);
        requestCodeParam = method.param(codeModel().INT, "requestCode");
        resultCodeParam = method.param(codeModel().INT, "resultCode");
        dataParam = method.param(getClasses().INTENT, "data");
        JBlock body = method.body();
        body.invoke(_super(), method).arg(requestCodeParam).arg(resultCodeParam).arg(dataParam);
        afterSuperBlock = body.blockSimple();
    }
}
